<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.jsdelivr.net/npm/vue "></script>
    <title>开关双向绑定</title>
</head>

<body>
    <div id="app">
        <div>
            <span>父：{{msg}}</span>
            <button v-on:click="change">{{msg}}</button>
        </div>
        <switch-button v-bind:result="msg" v-on:update:my-result="onChangeMyResult"></switch-button>
    </div>
    <template id="t1">
        <div>
            <span>子：{{myResult}}</span>
            <button @click="change">{{myResult}}</button>
        </div>
    </template>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: '开'
            },
            methods: {
                change: function () {
                    if (this.msg === '开') {
                        this.msg = '关'
                    }
                    else {
                        this.msg = '开'
                    }
                },
                onChangeMyResult: function (val) {
                    this.msg = val // 外部调用组件方注册变更方法，将组件内数据变更，同步到组件外的数据状态中
                }
            },
            components: {
                'switch-button': {
                    template: '#t1',
                    props: ['result'],
                    data: function () {
                        return {
                            myResult: this.result // 创建props属性result的副本--> myResult
                        }
                    },
                    methods: {
                        change: function () {
                            if (this.myResult === '开') {
                                this.myResult = '关'
                            }
                            else {
                                this.myResult = '开'
                            }
                        }
                    },
                    watch: {
                        result: function (val) {
                            console.log(val)
                            this.myResult = val // 监听外部对props属性result的变更,并同步到子组件的data属性myResult中
                        },
                        myResult: function (val1) {
                            this.$emit('update:my-result', val1) // myResult变更后通过$emit向外部父组件发送事件通知并传值val1
                        }
                    }
                }
            }
        })
//子组件不能直接向父组件传递数据，先定义props数据result然后在子组件data内创建props数据副本myResult
//然后在子组件通过v-on绑定监听事件change去监听props数据副本myResult
//再在子组件methods方法内执行change事件，判断组件状态或数据
//再在子组件内通过watch监听result和其副本myResult；其作用是
//1.监听外部父组件对props属性result的变更,并同步到子组件的data属性副本myResult中
//2.如果子组件内对myResult数据或状态变更后向外部父组件发送事件通知

    </script>
</body>

</html>